package cate.game.server.cli;

import cate.common.table.d.GDFunc;
import cate.game.GameBody;
import cate.game.ManyGame;
import cate.game.client.ClientContext;
import cate.game.client.msg.GameMsg;
import cate.game.common.time.TimeManager;
import easy.socket.handler.WsServerHandler;
import easy.socket.server.ServerProperties;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

@Slf4j
public class CliHandler extends WsServerHandler {

    private ManyGame games;

    public CliHandler(ServerProperties properties, ManyGame games) {
        super(properties);
        this.games = games;
    }

    @Override
    protected void handleTextWebSocketFrame(ChannelHandlerContext ctx, TextWebSocketFrame frame) {
        String content = frame.text();
        log.info("收到了text消息: {}", content);
        //ctx.writeAndFlush(new TextWebSocketFrame("你好"));
        if(StringUtils.equals(content, "logcat")) {
            this.games.logcat.addChannelCtx(ctx);
            this.games.logcat.log("system", "LOGCAT你好，已注册该日志服务");
        }
    }

    @Override
    protected void handleBinaryWebSocketFrame(ChannelHandlerContext ctx, BinaryWebSocketFrame frame) {
        GameMsg msg = null;
        GameBody game = null;
        try {
            msg = MsgDecode.decode(frame, ctx);
            game = games.get(msg.srvId);
            if(game == null) {
                log.error("在SomeGame中找不到srvId={}", msg.srvId);
                return;
            }
            if(!game.isRunning()) {
                log.debug("GameBody已不再运行");
                ctx.close();
                return;
            }
            game.client.request.onMsgInput(game, msg);
        } catch (Exception e) {
            game.client.request.onMsgInputException(game, msg, e);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        handleOffline(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        super.exceptionCaught(ctx, cause);
        handleOffline(ctx);
    }

    private void handleOffline(ChannelHandlerContext ctx) {
        NettyContextImpl nci = new NettyContextImpl(ctx);
        String cid = nci.cid();
        for(GameBody game : games.getAll()) {
            ClientContext cc = game.client.contextHolder.get(cid);
            if(cc != null && cc.getRole() != null) {
                game.client.contextHolder.unregister(cid);
                game.role.saveAndDrop(cc.getRole(), false);
            }
        }
        games.logcat.removeChannelCtx(ctx);
    }
}
